﻿#ifndef TTUCMD_H
#define TTUCMD_H
#include "ttucmd_global.h"
#include "QtSerialPort/QSerialPort"
#include <QString>
#include <QStringList>
#include <QMap>
#include <QTimer>
#include <QThread>
#include "custmHead.h"
#include "QtNetwork/QTcpSocket"
#include <../../include/sshconnection.h>
#include <../../include/sshremoteprocess.h>

#define WAITTIME 10000       //定时器等待时间

class TTUCMDSHARED_EXPORT TTucmd : public QObject
{
    Q_OBJECT
public:
    /**
     * @brief TTucmd    构造函数
     * @param devtype   设备类型 0:华为，1:智芯，默认0.
     * @param index     设备号
     * @param user      用户名
     * @param key       密码
     */
    TTucmd(int devtype=0,int index=-1,const QString &user = "admin",const QString &key = "Admin@huawei");

    ~TTucmd();

    struct _ContainerInfo{//容器信息存储
        int index;
        QString name;
        QString version;
        QString pathcVersion;
        QString status;
        QString ip;
        float cpUsage;//cpu占用率 %
        QString maxMem;
        float memUsage;//
        QString diskSize;
        float diskUsage;

        _ContainerInfo(){
            //memset(this,-1,sizeof(_ContainerInfo));
            index=-1;
            cpUsage=-1;
            memUsage=-1;
            diskUsage=-1;
            name="";
            version="";
            pathcVersion="";
            status="";
            ip="";
            maxMem="";
            diskSize="";
        }
    };


    struct _AppInfo{//app信息存储
        int index;
        QString name;
        QString version;
        QString hash;
        bool isVerified;
        int serviceIndex;
        QString serviceName;
        bool serviceEnable;
        QString servicStatus;
        float cpuThreshold;
        float cpUsage;//cpu占用率 %
        QString memThreshold;
        QString memUsage;//
        QString startTime;

        _AppInfo(){
            //memset(this,-1,sizeof(_AppInfo));
            index=-1;
            isVerified=false;
            serviceIndex=-1;
            serviceEnable=false;
            cpuThreshold=-1;
            cpUsage=-1;
            name="";
            version="";
            hash="";
            serviceName="";
            servicStatus="";
            startTime="";
            memThreshold="";
            memUsage="";
        }
    };

    /****************串口通信***************/
    /**
     * @brief setSerialArgs 设置串口
     * @param portname 串口号
     * @param baudrate 波特率
     * @param parity 校验位0-NoParity，1-OddParity，2-EvenParity，3-SpaceParity，4-MarkParity，-1-UnknownParity
     * @param databits 数据位5-8对应data5-data8
     * @param stopbits 停止位0-OneStop，1-OneAndHalfStop，2-TwoStop
     */
    void setSerialArgs(QString portname,unsigned int baudrate,int parity,int databits=8,int stopbits=0);
    void setSerialArgs(QString ip, int port);

public:
    bool openPort(int flag=0);    //0:ssh，1：com，
    void closePort(int flag=0);    //0:ssh，1：com，2：ssh

    /**命令交互**/


    /**
     * @brief getVersion 获取设备版本
     * @return 设备版本号，若出错则返回空
     */
    void getVersion();

    //scu获取硬件版本
    void getScuVersion();

    /**
     * @brief getCPUInfo 获取cpu信息
     */
    void getCPUInfo();

    /**
     * @brief checkOnline 查询是否上线,判断完回复还是直接回复需要再看
     */
    void checkOnline();

    /**
     * @brief getContainerSts 获取容器信息，包含容器是否运行，容器名
     */
    void getContainerSts();
    /**
     * @brief stopContainer 停止容器
     * @param name 容器名
     */
    void stopContainer(QString name="lxc01");
    /**
     * @brief startContainer 启动容器
     * @param name 容器名
     */
    void startContainer(QString name="lxc01");
    void queryProcess();
    /**
     * @brief getAppInfo 获取容器信息
     * @param contname
     */
    void getAppInfo(QString contname="lxc01");
    /**
     * @brief stopApp 暂停app
     * @param contname 容器名
     * @param Appname app名
     */
    void stopApp(QString contname="lxc01", QString Appname="IEC");
    /**
     * @brief startApp 启动容器app
     * @param contname 容器名
     * @param Appname app名
     */
    void startApp(QString contname="lxc01", QString Appname="IEC");
    /**
     * @brief copyApp 拷贝安装包（*.ova）到设备中
     * @param frompath 本机路径
     * @param topath 目标路径
     */
    void copyApp(QString frompath="ftp://192.168.101.111/IEC.ova",QString topath="/mnt/internal_storage/test.ova");
    /**
     * @brief installApp 安装app
     * @param contname 容器名，
     * @param apppath app包(*.ova)路径
     */
    void installApp(QString contname="lxc01",QString apppath="/mnt/internal_storage/test.ova");

    /**
     * @brief uninstallApp 卸载app，
     * @param contname 容器名
     * @param appname 卸载app名
     */
    void uninstallApp(QString contname="lxc01",QString appname="test");

    /**
     * @brief 设置文件权限
     * @param 权限等级 777
     * @param 文件名
     */
    void SetAuthority(QString PermissionLevel = "777", QString FileName = "uarttest11");

    /**
     * @brief 启动可执行程序
     * @param[in] 可执行程序路径
     */
    void StartExeProgram(QString ExePath = "./uarttest11");

    /**
     * @brief 组合键输出
     * @param[in] 组合键 ctrl+C
     */
    void SetCombinationKeys(QString Keys = QString(char(03)));

    /**
     * @brief 容器重启
     * @param[in] 容器名称
     */
    void RestartContainer(QString ContainerName = "c_yinxiao");

    /**
     * @brief getESN 获取终端esn编码
     */
    void getESN();
    /**
     * @brief getSysVersion获取终端系统版本
     */
    void getSysVersion();

    /**
     * @brief getAppVersion 读APP版本
     */
    void getAppVersion(QString contain,QString app);

    void GpsTime();

    void BdTime();

    void GPSAndBdTime();

    void GpsPos();

    void BdPos();

    void GPSAndBdPos();

    /**
     * @brief mapInterAcess 增加网口映射
     */
    void mapInterAcess();

    /**
     * @brief setTTUIP 设置设备IP
     * @param ip IP值
     */
    void setTTUIP(QString ip);

    /******以下为增加规则表相关函数**************/
    void setIp(QString ip);
    /**
     * @brief setStep   设置网口映射的步骤，默认0
     * @param step      步骤
     */
    void setStep(int step=0);
    /**
     * @brief setNetMap
     * @param ip1 网口ip  192.168.8.101/24
     * @param ip2 容器ip  192.168.100.252/2404
     */
    void setNetMap(QString ip1="192.168.8.101/24", QString ip2="192.168.100.252:2404");

    /**
     * @brief getAllIp  获取所有IP地址
     */
    void getAllIp();

    /**
     * @brief delOldIP  删除旧的ip
     */
    void delOldIP(QString ip);

    /**
     * @brief rebootDev 重启设备
     */
    void rebootDev();

    /**
     * @brief writeUserName 输入用户名
     */
    void writeUserName();
    /**
     * @brief writePassword 输入密码
     */
    void writePassword();


    /****融合终端相关命令*****/
    /**
     * @brief changUsr
     * @param usr   0默认用户，1：root用户
     * @return
     */
    void changUsr(int usr) ;
    /**
     * @brief ExitVim   退出vim编辑器
     * @param cmd   退出方式
     * @return
     */
    TTucmd &ExitVim(const QString &cmd = ":q"){
        if(!sendCmd(cmd,"\r")){ //因为用到sendcmd中修改了类成员变量，所以无法声明为const函数
            qerr << g_C2Q("退出vim失败");
        }
        return *this;
    }
    TTucmd &ForceExitVim(const QString &cmd = ":q!") { return ExitVim(cmd);}
    TTucmd &SaveExitVim(const QString &cmd = ":wq") { return ExitVim(cmd);}

    void FindText(const QString &text) ;

    void deletLine() ;

    void EditBeforeLine() ;
    void insertText(const QString &text) ;
    /**
     * @brief openFile用vim打开文件
     * @param name  文件路径名，包含文件名，vi不需要
     * @return
     */
    void openFile(const QString &name) ;

    /**
     * @brief startSSH  开启ssh
     * @return
     */
    void startSSH() ;

    void sendData(QString data){
        sendCmd(data);
    }

signals:
    void RespondsetTTUIP(int,bool);//设置ip结果
    void RespondgetVersion(int,QString);//获取软件版本号
    void RespondgetScuVersion(int,QString);//获取软件版本号
    void RespondgetCPUInfo(int,QMap<QString,QString>);//cpu信息键值对形式，硬件版本号，cpu占用率等
    void RespondcheckOnline(int,bool);//设备是否上线
    void RespondQueryProcess(int,bool);
    void RespondgetContainerSts(int,QList<TTucmd::_ContainerInfo>);//容器状态，容器cpu占用率，容器名，app名
    void RespondstopContainer(int,QString,bool);//停止容器，容器名，结果
    void RespondstartContainer(int,QString,bool);//启动容器，
    void RespondgetAppInfo(int,QList<TTucmd::_AppInfo>);//获取app信息,存在多个app
    void RespondstopApp(int,QString,QString,bool);//停止app
    void RespondstartApp(int,QString,QString,bool);//容器名，app名，结果
    void RespondcopyApp(int,QString,QString,bool);
    void RespondinstallApp(int,QString,QString,bool);
    void ResponduninstallApp(int,QString,QString,bool);//容器名，app名，结果
    void RespondNetMap(int,QString,bool);                          //网口映射

    void SendCmdMsg(int,QString);
    void RevCmdMsg(int,QString);

    void RespondPos(int index,QString x,QString y, QString z);
    void RespondTime(int index,bool);

    void RespondESN(int index,QString esn);
    void ResondSysVersion(int index,QString version);

    void ResondAppVersion(int index,QString appVersion);
    void SshStateChanged(int index,bool res);
private:
    int linkModel;  //0:socket, 1:com
    const QString mUser;        //用于登录的用户名
    const QString mKey;         //用于登录的密码
    const int mDeviceType;      //设备类型，0:华为，1:智芯，默认0.
    bool isFuseTermMap;              //融合终端网口设置时不考虑回复，

    QStringList mRoleTable; //规则表
    int mRoleIndex;         //规则表序号
    QTimer *mpTimer;        //定时器，网口映射用
    QSerialPort *mSerial;   //串口
    //QTcpSocket *mSocket;    //网口
    const int mDevIndex;    //设备号
    QStringList RoleList;   //规则表列表名
    bool mRevOKFlag;        //回复成功标志
    int miSteps;            //规则表步骤
    int mTotalSteps;        //总步骤
    QString mIp;            //网口ip
    QString mNetMapIp1;     //网口映射网口Ip
    QString mNetMapIp2;     //网口映射容器Ip
    QStringList mOldIpList; //原有的网口ip

    struct portArgs{
        QString PortName;
        unsigned int BaudRate;
        int Parity;
        int DataBits;
        int StopBits;

        QString IP; //网口ip
        int port;   //端口号
        QString StrIpPort;
    }mPortArgs;

    QByteArray RevData;
    QString mLastSendCmd;
    //enum

    void confirmRebootDev();
    bool sendCmd(QString cmd,QString endstr="\r\n");
    bool sendSudoCmd(QString cmd,QString endstr="\r\n");
    QString Hex2Str(QByteArray array);

    QByteArray Str2Hex(QString str);
    bool handleData(QString cmd,QString revdata);
    bool login(QString str);
    /***********************************
     * 网口映射操作
     * **********************************/
    void QueryRuleTable();

    void DelRuleTable(QString tname);

    void addRuleTable();

    void addChain(QString cmd);

    void addNetMapping();
    void filterRevMsg(QString &msg);
    int matchEndText(QString &revstr);
    //**************************************

private slots:
    void readData();
    void errorOccurred(QAbstractSocket::SocketError);
    void HandleTimeout();


    //以下为ssh内容:
private:
    QSsh::SshConnectionParameters m_argParameters;
    QSsh::SshConnection *m_pSshSocket;
    QSharedPointer<QSsh::SshRemoteProcess> m_shell;

    bool m_bConnected;

    void initParams();

    QString getIpPort(){return mPortArgs.IP + ":" + QString::number(mPortArgs.port);}

private slots:
    void slotConnected();
    void slotSshConnectError(QSsh::SshError sshError);

    //shell slots
    void slotShellStart();
    void slotShellError();

};

#endif // TTUCMD_H
